﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShevaEngine.Core.Modules.Graphics.Foundation;
using ShevaEngine.Core.Foundation.SphericalHarmonics;
using ShevaEngine.Core.Modules.Graphics;

namespace ShevaDeferredRenderer.Lights
{
    /// <summary>
    /// Ambient Light.
    /// </summary>
    public class AmbientLight
    {
        /// <summary>Viewport.</summary>
        public GraphicsViewport Viewport;
        /// <summary>The shader effect.</summary>
        private Effect Effect;        
        /// <summary>The ambient light color When the light pre pass is cleared this color is used to fill the buffer.
        /// The intensity property doesn’t affect this color.</summary>         
        public Color Color = new Color(0, 0, 0);
        /// <summary>Light intensity. The intensity doesn’t affect the color property.</summary>
        private float intensity = 0.01f;
        /// <summary>Ambient Occlusion Strength.</summary>
        public float AmbientOcclusionStrength = 5;
        /// <summary>Spherical Harmonic Ambient Light. They are great for store low frequency ambient colors and are very fast.</summary>
        public SphericalHarmonicL2 SphericalHarmonicAmbientLight;
        /// <summary>Ambient Occlusion Effect. If null no ambient occlusion will be used.</summary>
        //public AmbientOcclusion AmbientOcclusion;
        /// <summary>Light intensity. The intensity doesn’t affect the color property.</summary>
        public float Intensity
        {
            get { return intensity; }
            set
            {
                intensity = value;
                if (intensity < 0)
                    intensity = 0;
            }
        }         

        /// <summary>
        /// Constructor.
        /// </summary>
        public AmbientLight(GraphicsViewport viewport)
        {
            this.Viewport = viewport;

            this.Effect = ShevaEngine.Core.ShevaEngine.Instance.Content.Load<Effect>(@"Effects\LightPrePass\AmbientLight");

            if (this.SphericalHarmonicAmbientLight == null)
            {
                this.SphericalHarmonicAmbientLight = new SphericalHarmonicL2();
                this.SphericalHarmonicAmbientLight.Fill(1, 1, 1);
                //this.SphericalHarmonicAmbientLight.Fill(0, 0, 0);
            }
        }


        /// <summary>
        /// Render to the light pre pass texture.
        /// </summary>
        public void Render(RenderTarget2D normalMap, RenderTarget2D lightPrePassMap)
        {
            this.Effect.Parameters["HalfPixel"].SetValue(new Vector2(-1f / lightPrePassMap.Width, 1f / lightPrePassMap.Height));
            this.Effect.Parameters["NormalMapHV2"].SetValue(normalMap);
            this.Effect.Parameters["sphericalHarmonicBase"].SetValue(this.SphericalHarmonicAmbientLight.Coeficients);
            this.Effect.Parameters["intensity"].SetValue(this.Intensity);
            this.Effect.Parameters["viewI"].SetValue(Matrix.Invert(this.Viewport.Camera.ViewMatrix));
            this.Effect.Parameters["ambientOcclusionStrength"].SetValue(this.AmbientOcclusionStrength);

            //if (AmbientOcclusion == null)
                this.Effect.CurrentTechnique = Effect.Techniques["AmbientLightSH"];
            //else
            //{
            //    this.Effect.CurrentTechnique = Effect.Techniques["AmbientLightSHSSAO"];
            //    // And finally to the ambient light shader.
            //    this.SetAmbientOcclusionTexture(AmbientOcclusion.AmbientOcclusionTexture);
            //}

            this.Effect.CurrentTechnique.Passes[0].Apply();

            ScreenPlane.Instance.Render();
        }
    }
}
